package pub.guoxin.oops.analysis.service.impl;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.DecoderException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import pub.guoxin.oops.analysis.service.CommunicationService;
import pub.guoxin.oops.analysis.service.DataAnalysisService;
import pub.guoxin.oops.constants.TopicName;
import pub.guoxin.oops.model.*;
import pub.guoxin.oops.msg.MessageDataProducer;
import pub.guoxin.oops.repository.CommunicationRepository;
import pub.guoxin.oops.repository.DeviceDataInfoRepository;
import pub.guoxin.oops.repository.RealTimeCommunicationRepository;
import pub.guoxin.oops.repository.RealTimeDeviceDataInfoRepository;

import java.nio.charset.CharacterCodingException;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * Created by guoxin on 17-10-26.
 */
@Slf4j
@Service
public class CommunicationServiceImpl implements CommunicationService {

    @Autowired
    private DataAnalysisService dataAnalysisService;

    @Autowired
    private CommunicationRepository communicationRepository;
    @Autowired
    private DeviceDataInfoRepository deviceDataInfoRepository;
    @Autowired
    private RealTimeCommunicationRepository realTimeCommunicationRepository;
    @Autowired
    private RealTimeDeviceDataInfoRepository realTimeDeviceDataInfoRepository;
    @Autowired
    private MessageDataProducer producer;

    @Override
    public Boolean persistentData(String data) {
        log.info("接收数据: {}", data);
        Communication communication;
        List<DeviceDataInfo> devices;
        try {
            communication = dataAnalysisService.analysisCommunicationData(data);
            devices = dataAnalysisService.analysisDeviceInfoData(data);
        } catch (DecoderException | CharacterCodingException e) {
            e.printStackTrace();
            log.info("Analysis collector field {}", e);
            return false;
        }
        if (Objects.isNull(communication)) {
            log.info("communication is null");
            return false;
        }
        log.info("模块数据: {}", communication.toString());
        log.info("流量数据: {}", devices.toString());
        // 关联设备与通讯模块
        devices.forEach(device -> device.setCommunicationId(communication.getSn()));

        saveRTCommunication(communication);
        saveRTDeviceDataInfo(devices, communication.getSn());

        Communication communicationResult = communicationRepository.findByDateTimeAndSn(
                communication.getDateTime(), communication.getSn());
        if (Objects.isNull(communicationResult)) {
            communicationRepository.save(communication);
            deviceDataInfoRepository.save(devices);
        }
        CommunicationData build = CommunicationData.builder().communication(communication).deviceDataInfos(devices).build();
        producer.sender(TopicName.DATA_ALARM_TOPIC, build);
        return true;
    }

    /**
     * 保存实时通信设备数据
     *
     * @param devices
     * @param realTimeCommunicationId
     */
    private void saveRTDeviceDataInfo(List<DeviceDataInfo> devices, String realTimeCommunicationId) {
        List<RealTimeDeviceDataInfo> collect = devices.stream().map(device -> device.realTime(realTimeCommunicationId)).collect(Collectors.toList());
        realTimeDeviceDataInfoRepository.save(collect);
    }

    /**
     * 保存实时通讯模块数据
     *
     * @param communication
     * @return
     */
    private void saveRTCommunication(Communication communication) {
        RealTimeCommunication realTimeCommunication = communication.realTime();
        RealTimeCommunication result = realTimeCommunicationRepository.findOne(communication.getSn());
        if (Objects.nonNull(result)) {
            realTimeCommunication.setCompanyId(result.getCompanyId());
            realTimeCommunication.setGroupId(result.getGroupId());
        }
        realTimeCommunicationRepository.save(realTimeCommunication);
    }

}
